package com.huaxin.hxcloud.activity;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import com.baidu.mapapi.search.core.RouteLine;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.huaxin.common.BaseActivity;
import com.huaxin.common.Constants;
import com.huaxin.common.Entity.CLatLng;
import com.huaxin.common.Entity.TaskRoutDTO;
import com.huaxin.common.Entity.VehicleRecord;
import com.huaxin.common.message.overlayutil.OverlayManager;
import com.huaxin.common.tools.HxTransmitRequestHelper;
import com.huaxin.common.utils.AdaptiveMapLevelUtil;
import com.huaxin.common.utils.ToastUtil;
import com.huaxin.hxcloud.R;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * @author lwjing
 * @date 2018/3/15
 * @Desc $desc$
 * Copyright HUAXIN DATA. All rights reserved.
 */
public class HxWorkTaskRoutActivity extends BaseActivity implements BaiduMap.OnMapLoadedCallback, SensorEventListener, View.OnClickListener {
    //  OnGetRoutePlanResultListener,
    @BindView(R.id.toolbar)
    Toolbar   toolbar;
    @BindView(R.id.map)
    MapView   mMapView;
    @BindView(R.id.btn_route)
    Button    btn_route;
    @BindView(R.id.btn_location)
    Button    btn_location;
    @BindView(R.id.iv_start_route)
    ImageView iv_start_route;

    private VehicleRecord vehicleRecord;
    private BaiduMap      mBaiduMap;
    private boolean toLoc = false;

    boolean useDefaultIcon = false;
    // 搜索相关
    //RoutePlanSearch mSearch        = null;    // 搜索模块，也可去掉地图模块独立使用

    DrivingRouteResult nowResultdrive = null;
    //int                nodeIndex        = -1; // 节点索引,供浏览节点时使用
    OverlayManager     routeOverlay   = null;
    // boolean            hasShownDialogue = false;
    RouteLine          route          = null;
    private SensorManager                        mSensorManager;
    private LocationClient                       mLocClient;
    private MyLocationConfiguration.LocationMode mCurrentMode;
    private MyLocationConfiguration              mConfiguration;
    private BitmapDescriptor                     mCurrentMarker;
    private Polyline                             mPolyline;
    private BitmapDescriptor                     startBitmapDescriptor;
    private BitmapDescriptor                     endBitmapDescriptor;
    private int                                  arrangeId;
    private Marker                               mMoveMarker;  //轨迹行驶mark

    // 通过设置间隔时间和距离可以控制速度和图标移动的距离
    private static final int    TIME_INTERVAL = 100;
    //    private static final double DISTANCE      = 0.00002;
    private static final double DISTANCE      = 0.02;
    private Handler      mHandler;
    private List<LatLng> mPoints;
    private int mLevel = -1;
    private LatLng   center;
    private boolean  isPuase; //路线回放是否暂停
    private MyThread mMyThread;

    @Override
    protected int getContentViewId() {
        return R.layout.activity_vehilcle_rout;
    }

    @Override
    public int getLoadFrameId() {
        return R.id.content;
    }

    @Override
    protected void getBundleExtras(Bundle extras) {
        super.getBundleExtras(extras);
        if (extras.containsKey(Constants.IK_ARRANGE_ID)) {
            arrangeId = extras.getInt(Constants.IK_ARRANGE_ID);
        } else {
            finish();
        }
    }

    @Override
    public void initView() {
        super.initView();
        setSupportActionBar(toolbar);
        toolbar.setTitle("行车路线");
        updateLoadStatus(LOADING);
        mBaiduMap = mMapView.getMap();
        mBaiduMap.setOnMapLoadedCallback(this);
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        // initSeacher();
        initLocation();
        mHandler = new Handler(Looper.getMainLooper());

    }

    @Override
    protected void requestData() {
        super.requestData();
        apiArrangeTaskStationList();
    }

    /**
     * 获取路径和站点信息
     */
    private void apiArrangeTaskStationList() {
        //  updateLoadStatus(LOADING);
        Call<TaskRoutDTO> call = HxTransmitRequestHelper.getRequestApi().getArrangeTaskStationList(arrangeId);
        autoClose(call);
        call.enqueue(new Callback<TaskRoutDTO>() {
            @Override
            public void onResponse(Call<TaskRoutDTO> call, Response<TaskRoutDTO> response) {
                TaskRoutDTO taskRoutDTO = response.body();
                //   updateLoadStatus(LOAD_SUCCESS);
                if (response.isSuccessful() && taskRoutDTO != null) {
                    TaskRoutDTO.TaskRout data = taskRoutDTO.getData();
                    if (data != null) {
                        List<CLatLng> routes = data.getRoute();
                        //至少两点才能画线
                        if (routes != null && routes.size() > 2) {
                            setRouteOverlay(routes);
                            //自适应地图缩放级别
                            AdaptiveMapLevelUtil instance = AdaptiveMapLevelUtil.getInstance();
                            mLevel = instance.getlevel(mPoints);
                            center = instance.getCenter();
                            Log.e("lwjing", "location level=" + mLevel);
                            //设置地图显示级别为计算所得level
                            mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(mLevel).build()));
                            MapStatusUpdate status1 = MapStatusUpdateFactory.newLatLng(center);
                            mBaiduMap.animateMapStatus(status1, 500);
                        } else {
                            ToastUtil.showToast("暂无路线");
                        }
                        List<TaskRoutDTO.StationInfo> stationMessage = data.getStationMessage();
                        if (stationMessage != null && stationMessage.size() > 0) {
                            setStationMark(stationMessage);
                        }
                    }

                }
            }

            @Override
            public void onFailure(Call<TaskRoutDTO> call, Throwable t) {
                // updateLoadStatus(LOAD_SUCCESS);
            }
        });
    }

    public void setStartEndMark(List<CLatLng> routes) {
        startBitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.icon_st);
        endBitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.icon_en);
        LatLng startPoint = new LatLng(routes.get(0).getLat(), routes.get(0).getLng());
        LatLng endPoint = new LatLng(routes.get(routes.size() - 1).getLat(), routes.get(routes.size() - 1).getLng());

        //        Bundle bundle = new Bundle();
        //        bundle.putParcelable(Constants.IK_STATION, station);
        MarkerOptions startMarkerOption = new MarkerOptions()
                .position(startPoint)
                .icon(startBitmapDescriptor);
        //可设置附带信息,在点击事件的时候可获得
        //    .extraInfo(bundle);
        mBaiduMap.addOverlay(startMarkerOption);
        MarkerOptions endMarkerOption = new MarkerOptions().position(endPoint).icon(endBitmapDescriptor);
        mBaiduMap.addOverlay(endMarkerOption);
        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                //弹出停留时间
                showMarkInfo(marker);
                return false;
            }
        });

    }

    public void setStationMark(List<TaskRoutDTO.StationInfo> stationInfos) {
        List<OverlayOptions> optionList = new ArrayList<>();
        List<LatLng> points = new ArrayList<LatLng>();
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (TaskRoutDTO.StationInfo station : stationInfos) {
            if (!(station.getLat() == 0.0) || !(station.getLng() == 0.0)) {

                Log.d(TAG, "initMark: ---->" + station.toString());
                Bundle bundle = new Bundle();
                bundle.putParcelable(Constants.IK_STATION, station);
                LatLng point = new LatLng(station.getLat(), station.getLng());
                points.add(point);
                builder = builder.include(point);
                MarkerOptions option = new MarkerOptions()
                        .position(point)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_normal))
                        .extraInfo(bundle);
                //                    .animateType(MarkerOptions.MarkerAnimateType.drop);
                optionList.add(option);
            }
        }
        //  setRouteOverlayLatLng(points);
        mBaiduMap.addOverlays(optionList);

        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                TaskRoutDTO.StationInfo stationInfo = marker.getExtraInfo().getParcelable(Constants
                        .IK_STATION);
                View v = mInflater.inflate(R.layout.task_rout_stationinfo, null);
                TextView tvStationName = (TextView) v.findViewById(R.id.tv_station_name);
                TextView tvStationAddress = (TextView) v.findViewById(R.id.tv_station_address);
                TextView tv_signin_time = (TextView) v.findViewById(R.id.tv_signin_time);
                TextView tv_signout_time = (TextView) v.findViewById(R.id.tv_signout_time);
                TextView tv_work_time = (TextView) v.findViewById(R.id.tv_work_time);
                loadText(tvStationName, stationInfo.getName());
                tvStationAddress.setText(stationInfo.getAddress());
                if (stationInfo.getSignInTime() != 0) {
                    loadTextColon(tv_signin_time, "签到时间", dateFormat1(stationInfo.getSignInTime()));
                }
                if (stationInfo.getSignOutTime() != 0) {
                    loadTextColon(tv_signout_time, "签退时间", dateFormat1(stationInfo.getSignOutTime()));
                }
                if (stationInfo.getSignInTime() != 0 && stationInfo.getSignOutTime() != 0) {
                    loadTextColon(tv_work_time, "工作时长", howLongTime(stationInfo.getSignOutTime(), stationInfo.getSignInTime()));
                }
                final LatLng ll = marker.getPosition();
                InfoWindow mInfoWindow = new InfoWindow(v, ll, -47);
                mBaiduMap.showInfoWindow(mInfoWindow);

                return true;
            }
        });
    }

    private void showMarkInfo(Marker marker) {
        View v = mInflater.inflate(R.layout.info_station, null);
        TextView tvStationName = (TextView) v.findViewById(R.id.tv_station_name);
        TextView tvStationAddress = (TextView) v.findViewById(R.id.tv_station_address);
        //  loadText(tvStationName, "站点");
        // loadText("停留时间：", tvStationAddress, "3小时", "暂无");

        final LatLng ll = marker.getPosition();
        InfoWindow mInfoWindow = new InfoWindow(v, ll, -47);
        mBaiduMap.showInfoWindow(mInfoWindow);

    }

    /**
     * @desc 初始定位
     * @author songxf
     * created at 2017/7/12 16:03
     */
    private void initLocation() {
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);//获取传感器管理服务
        //开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        //定位初始化
        mLocClient = new LocationClient(this);
        mLocClient.registerLocationListener(new MyLocationListenner());
        mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL;
        mConfiguration = new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker);
        mBaiduMap.setMyLocationConfigeration(mConfiguration);
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(0);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于
        mLocClient.setLocOption(option);
        mLocClient.start();
    }

    @OnClick({R.id.btn_location, R.id.btn_route, R.id.iv_start_route})
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_location:
                //定位
                isFirstLoc = true;
                initLocation();
                break;
            case R.id.btn_route:
                //显示路线
                Log.e("lwjing", "location level=" + mLevel);
                if (mLevel == -1) {
                    AdaptiveMapLevelUtil instance = AdaptiveMapLevelUtil.getInstance();
                    mLevel = instance.getlevel(mPoints);
                    center = instance.getCenter();
                }
                //设置地图显示级别为计算所得level
                mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(mLevel).build()));
                MapStatusUpdate status1 = MapStatusUpdateFactory.newLatLng(center);
                mBaiduMap.animateMapStatus(status1, 500);

            case R.id.iv_start_route:
                //TODO 路线回放
                if (mPoints == null || mPoints.size() < 2) {
                    ToastUtil.showToast("暂无路线");
                    return;
                }
                if (mMoveMarker == null) {
                    OverlayOptions markerOptions = new MarkerOptions().flat(true)
                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)).position(mPoints.get(0));
                    //.rotate((float) getAngle(0))
                    mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions);
                }
                //false--->true 暂停到回放
                isPuase = !isPuase;
                if (isPuase) {
                    iv_start_route.setImageResource(R.drawable.icon_route_stop);
                    //TODO 移动行驶轨迹
                    moveLooper();

                } else {
                    iv_start_route.setImageResource(R.drawable.icon_route_start);
                    //TODO 暂停轨迹
                    stopmoveLooper();
                }
                break;
        }
    }

    public class MyLocationListenner implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // map view 销毁后不在处理新接收的位置
            if (location == null || mBaiduMap == null) {
                return;
            }

            mCurrentAccracy = location.getRadius();
            locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mCurrentDirection).latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            mBaiduMap.setMyLocationData(locData);
            if (isFirstLoc) {
                isFirstLoc = false;
                LatLng ll = new LatLng(location.getLatitude(),
                        location.getLongitude());
                //不改变地图level 只将当前位置改为地图显示中心点
                MapStatusUpdate status1 = MapStatusUpdateFactory.newLatLng(ll);
                mBaiduMap.animateMapStatus(status1, 500);
            }
        }
    }

    /**
     * 定位SDK监听函数
     */
    private int    mCurrentDirection = 0;
    private double mCurrentLat       = 0.0;
    private double mCurrentLon       = 0.0;
    private float          mCurrentAccracy;
    private MyLocationData locData;
    boolean isFirstLoc = true; // 是否首次定位
    private Double lastX = 0.0;

    /**
     * @desc 罗盘 旋转改变
     * @author songxf
     * created at 2017/7/12 16:22
     */
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        double x = sensorEvent.values[SensorManager.DATA_X];
        if (Math.abs(x - lastX) > 1.0) {
            mCurrentDirection = (int) x;
            locData = new MyLocationData.Builder()
                    .accuracy(mCurrentAccracy)
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mCurrentDirection).latitude(mCurrentLat)
                    .longitude(mCurrentLon).build();
            mBaiduMap.setMyLocationData(locData);
        }
        lastX = x;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    @Override
    public void onMapLoaded() {
        updateLoadStatus(LOAD_SUCCESS);


    }

    public void setRouteOverlay(List<CLatLng> routes) {
        //设置终起点icon
        setStartEndMark(routes);

        // 添加普通折线绘制
        mPoints = new ArrayList<>();
        //        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (CLatLng latLng : routes) {
            LatLng ltg = new LatLng(latLng.getLat(), latLng.getLng());
            mPoints.add(ltg);
            //            builder.include(ltg);
        }
        PolylineOptions polylineOptions = new PolylineOptions().points(mPoints).width(12).color(getResources().getColor(R.color.view_green));
        mPolyline = (Polyline) mBaiduMap.addOverlay(polylineOptions);
        //以防定位后 改变地图缩放级别
        isFirstLoc = false;
    }

    Thread thread = new Thread() {
        public void run() {

            //                while (true) {
        }

    };

    private class MyThread extends Thread {
        private final Object  lock  = new Object();
        private       boolean pause = false;

        /**
         * 调用这个方法实现暂停线程
         */
        void pauseThread() {
            pause = true;
        }

        /**
         * 调用这个方法实现恢复线程的运行
         */
        void resumeThread() {
            pause = false;
            synchronized (lock) {
                lock.notifyAll();
            }
        }

        /**
         * 注意：这个方法只能在run方法里调用，不然会阻塞主线程，导致页面无响应
         */
        void onPause() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {
            super.run();
            try {
                int index = 0;
                while (true) {
                    // 让线程处于暂停等待状态
                    while (pause) {
                        onPause();
                    }
                    for (int i = 0; i < mPoints.size() - 1; i++) {
                        final LatLng startPoint = mPoints.get(i);
                        final LatLng endPoint = mPoints.get(i + 1);
                        //两点斜率
                        double slope = getSlope(startPoint, endPoint);
                        // 是不是正向的标示
                        boolean isReverse = (startPoint.latitude > endPoint.latitude);
                        //根据点和斜率算取截距
                        double intercept = getInterception(slope, startPoint);
                        //计算x方向每次移动的距离
                        double xMoveDistance = isReverse ? getXMoveDistance(slope) :
                                -1 * getXMoveDistance(slope);

                        Log.e("lwjing", "slope=" + slope + " intercept=" + intercept + " xMoveDistance=" + xMoveDistance);

                        for (double j = startPoint.latitude; !((j > endPoint.latitude) ^ isReverse); j = j - xMoveDistance) {
                            LatLng latLng = null;
                            if (slope == Double.MAX_VALUE) {
                                latLng = new LatLng(j, startPoint.longitude);
                            } else {
                                latLng = new LatLng(j, (j - intercept) / slope);
                            }
                            final LatLng finalLatLng = latLng;
                            Log.e("lwjing", "x=" + finalLatLng.latitude + " y=" + finalLatLng.longitude);
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    if (mMapView == null) {
                                        return;
                                    }
                                    mMoveMarker.setPosition(finalLatLng);
                                }
                            });
                            try {
                                Thread.sleep(TIME_INTERVAL);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                                break;
                            }
                        }

                    }
                }
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 循环进行移动逻辑
     */
    public void moveLooper() {
        if (mMyThread == null) {
            mMyThread = new MyThread();
            Thread thread = new Thread(mMyThread);
            thread.start();
        } else {
            mMyThread.resumeThread();
        }

    }

    private void stopmoveLooper() {
        mMyThread.pauseThread();
    }

    /**
     * 算斜率
     */
    private double getSlope(LatLng fromPoint, LatLng toPoint) {
        if (toPoint.longitude == fromPoint.longitude) {
            return Double.MAX_VALUE;
        }
        double slope = ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude));
        return slope;

    }

    /**
     * 根据点和斜率算取截距
     */
    private double getInterception(double slope, LatLng point) {

        double interception = point.latitude - slope * point.longitude;
        return interception;
    }

    /**
     * 计算x方向每次移动的距离
     */
    private double getXMoveDistance(double slope) {
        if (slope == Double.MAX_VALUE) {
            return DISTANCE;
        }
        return Math.abs((DISTANCE * slope) / Math.sqrt(1 + slope * slope));
    }

    /**
     * 根据点获取图标转的角度
     */
    //    private double getAngle(int startIndex) {
    //        if ((startIndex + 1) >= mPolyline.getPoints().size()) {
    //            throw new RuntimeException("index out of bonds");
    //        }
    //        LatLng startPoint = mPolyline.getPoints().get(startIndex);
    //        LatLng endPoint = mPolyline.getPoints().get(startIndex + 1);
    //        return getAngle(startPoint, endPoint);
    //    }

    /**
     * 根据两点算取图标转的角度
     */
    //    private double getAngle(LatLng fromPoint, LatLng toPoint) {
    //        double slope = getSlope(fromPoint, toPoint);
    //        if (slope == Double.MAX_VALUE) {
    //            if (toPoint.latitude > fromPoint.latitude) {
    //                return 0;
    //            } else {
    //                return 180;
    //            }
    //        }
    //        float deltAngle = 0;
    //        if ((toPoint.latitude - fromPoint.latitude) * slope < 0) {
    //            deltAngle = 180;
    //        }
    //        double radio = Math.atan(slope);
    //        double angle = 180 * (radio / Math.PI) + deltAngle - 90;
    //        return angle;
    //    }
    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        //为系统的方向传感器注册监听器
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI);
        super.onResume();
    }

    @Override
    protected void onStop() {
        //取消注册传感器监听
        mSensorManager.unregisterListener(this);
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        // 退出时销毁定位
        mLocClient.stop();
        // 关闭定位图层
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        if (mMyThread !=null){
            mMyThread.interrupt();
        }
        super.onDestroy();
    }
}
